using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MyFrame.Pool;
using MyFrame.Single;
using Platform.Buff.Buffs;
using UnityEngine;

namespace Platform.Buff
{
    public class BuffFactory : SingletonMonoGlobal<BuffFactory>
    {
        // 类型缓存
        private static Dictionary<string, Type> typeCache = new Dictionary<string, Type>();
        // 属性缓存
        private static ConcurrentDictionary<Type, FieldInfo[]> PropertyCaches = new();

        public BuffDataSO buffData;
        private Dictionary<BuffType, BuffBase> buffBases = new();

        void Awake()
        {
            buffData = AAMgr.LoadAsset<BuffDataSO>("BuffData");
        }

        // public BuffBase GetBuff(BuffType buffType)
        // {
        //     return buffData.GetBuff(buffType);
        // }

        public BuffBase CreateBuff(BuffType buffType)// 创建对应算法
        {
            string className = string.Format("Platform.Buff.Buffs.{0}Buff", buffType.ToString());
            if (!typeCache.TryGetValue(className, out Type type))
            {
                // 如果缓存中没有该类型，反射获取并缓存
                type = Type.GetType(className);
                if (type != null)
                {
                    typeCache[className] = type;
                }
                else
                {
                    Debug.LogError($"Type {className} not found.");
                    return null;
                }
            }

            //给buff填充数据
            var BuffData = buffData.GetBuff(buffType);

            BuffBase buff = Activator.CreateInstance(type) as BuffBase;
            // BuffBase buff = PoolMgr.Instance.GetObj<BuffBase>();

            if (buff != null) CopyProperties(BuffData, buff);

            return buff;
        }
        public static void CopyProperties<T>(T source, T target)
        {
            if (source == null || target == null)
                throw new ArgumentNullException("Source or target cannot be null.");

            var properties = PropertyCaches.GetOrAdd(typeof(T), t => t.GetFields());
            foreach (var property in properties)
            {
                var value = property.GetValue(source);
                property.SetValue(target, value);
            }
        }

    }
}